/**
 * @Author: Jiang Zhongxun
 * @Date: 2024-10-06 20:26:30
 * @FilePath: /practiceProject/src/sys/userSys.c
 * @Description: 用户端接口。包含：发起查验申请，查验申请记录、修改驳回申请、删除办结记录。
 * @Copyright (c) 2024 by 蒋仲勋, All Rights Reserved.
 */
#include "../../include/server/userSys.h"
#include "../../include/db/dbDefinition.h"
#include "../../include/db/dbOperation.h"
#include "../../include/utils/utils.h"

/**
 * @description: 用户发起查验申请
 * @param {sqlite3} *db SQLite3数据库指针句柄
 * @param {char} *applyUser 申请人名称
 * @return {*} 成功返回0，失败返回非0的数
 */
int applyNewCheck(sqlite3 *db, char *applyUser)
{
    char checkItemName[50] = {0};
    char *errmsg = NULL;
    char sql[256] = {0};
    char *operationName = "checkInfo";
    char message[128] = {0};
    int ret;
    printf("请输入发起查验的项目名称: ");
    scanf("%s", checkItemName);
    sprintf(sql, "INSERT INTO %s (checkItemName, applyUser) VALUES ('%s', '%s');",
            CHECK_TABLE_NAME, checkItemName, applyUser);
    ret = execOperate(db, sql, &errmsg, operationName);
    if (0 != ret)
    {
        fprintf(stderr, "发起查验申请失败! %s\n", errmsg ? errmsg : "通用的SQL增删改操作error");
        return -1;
    }
    else
    {
        printf("发起查验申请成功!\n");
        // 记录日志
        snprintf(message, sizeof(message), "【%s】发起了新的查验申请", applyUser);
        logToLogInfoTable(db, OPERATELOG, message);
    }
    return 0;
}

/**
 * @description: 检索用户个人的所有查验申请记录
 * @param {sqlite3} *db SQLite3数据库指针句柄
 * @param {char} *applyUser 申请人名称
 * @return {*} 成功返回0，失败返回非0的数
 */
int searchCheckItem(sqlite3 *db, char *applyUser)
{
    char *errmsg = NULL;
    int row, column;
    char **result = NULL;
    char sql[256] = {0};
    char *operationName = "checkInfo";
    // char message[128] = {0};
    // int ret;
    sprintf(sql, "SELECT * FROM %s WHERE applyUser = '%s' AND isDelete = %d;",
            CHECK_TABLE_NAME, applyUser, DELETE_NO);
    // 调用 conditionQuery 执行查询操作
    result = conditionQuery(db, sql, &result, &row, &column, &errmsg, operationName);
    if (result == NULL)
    {
        fprintf(stderr, "查询失败: %s\n", errmsg ? errmsg : "未知错误");
        return -1;
    }
    if (0 == row)
    {
        printf("没有查到任何申请记录信息!\n");
    }
    else
    {
        // 悉数打印 row 行记录的数据
        int i, j;
        printf("=============================================== XX 海关进出口智慧查验平台 ================================================\n\n");
        for (i = 0; i <= row; i++)
        {
            for (j = 0; j < column; j++)
            {
                // 如果是 checkStatus 列
                if (j == 4)
                {
                    // 判断 checkStatus 的值，替换为对应的文字
                    if (0 == strcmp(result[i * column + j], "0"))
                    {
                        printf("未查验\t");
                    }
                    else if (0 == strcmp(result[i * column + j], "1"))
                    {
                        printf("已查验\t");
                    }
                    else if (0 == strcmp(result[i * column + j], "2"))
                    {
                        printf("已驳回\t");
                    }
                    else
                    {
                        printf("%s\t", result[i * column + j]); // 保持原样
                    }
                }
                else if (j == 5)
                {
                    // 判断 checkType 的值，替换为对应的文字
                    if (0 == strcmp(result[i * column + j], "0"))
                    {
                        printf("系统自动查验\t");
                    }
                    else if (0 == strcmp(result[i * column + j], "1"))
                    {
                        printf("人工手动查验\t");
                    }
                    else
                    {
                        printf("%s\t", result[i * column + j]); // 保持原样
                    }
                }
                else
                {
                    // 对于非 checkStatus 和 checkType 列，直接输出原值
                    printf("%s\t", result[i * column + j]);
                    // fflush(stdout); // 强制刷新缓冲区
                }
            }
            printf("\n");
            printf("--------------------------------------------------------------------------------------------------------------------------\n");
        }
        printf("\n                                   Copyright (c) 2024 by 蒋仲勋, All Rights Reserved                          \n");
        printf("=========================================================================================================================\n\n");
    }
    return 0;
}

/**
 * @description: 修改用户个人的驳回申请
 * @param {sqlite3} *db SQLite3数据库指针句柄
 * @return {*} 成功返回0，失败返回非0的数
 */
int updateCheckItem(sqlite3 *db, char *applyUser)
{
    char *errmsg = NULL;
    int row, column;
    char **result = NULL;
    char sql[256] = {0};
    char *operationName = "checkInfo";
    char message[128] = {0};
    int ret;
    int itemNum;                     // 选择的驳回申请的记录编号
    char newCheckItemName[20] = {0}; // 修改的查验项目名称
    sprintf(sql, "SELECT * FROM %s WHERE applyUser = '%s' AND checkStatus = %d AND isDelete = %d;",
            CHECK_TABLE_NAME, applyUser, CHECKFAILED, DELETE_NO);
    // 调用 conditionQuery 执行查询操作
    result = conditionQuery(db, sql, &result, &row, &column, &errmsg, operationName);
    if (result == NULL)
    {
        fprintf(stderr, "查询失败: %s\n", errmsg ? errmsg : "未知错误");
        return -1;
    }
    if (0 == row)
    {
        printf("没有查到任何已驳回信息!\n");
    }
    else
    {
        // 悉数打印 row 行记录的数据
        int i, j;
        printf("=============================================== XX 海关进出口智慧查验平台 ================================================\n\n");
        for (i = 0; i <= row; i++)
        {
            for (j = 0; j < column; j++)
            {
                // 如果是 checkStatus 列
                if (j == 4)
                {
                    // 判断 checkStatus 的值，替换为对应的文字
                    if (0 == strcmp(result[i * column + j], "0"))
                    {
                        printf("未查验\t");
                    }
                    else if (0 == strcmp(result[i * column + j], "1"))
                    {
                        printf("已查验\t");
                    }
                    else if (0 == strcmp(result[i * column + j], "2"))
                    {
                        printf("已驳回\t");
                    }
                    else
                    {
                        printf("%s\t", result[i * column + j]); // 保持原样
                    }
                }
                else if (j == 5)
                {
                    // 判断 checkType 的值，替换为对应的文字
                    if (0 == strcmp(result[i * column + j], "0"))
                    {
                        printf("系统自动查验\t");
                    }
                    else if (0 == strcmp(result[i * column + j], "1"))
                    {
                        printf("人工手动查验\t");
                    }
                    else
                    {
                        printf("%s\t", result[i * column + j]); // 保持原样
                    }
                }
                else
                {
                    // 对于非 checkStatus 和 checkType 列，直接输出原值
                    printf("%s\t", result[i * column + j]);
                    // fflush(stdout); // 强制刷新缓冲区
                }
            }
            printf("\n");
            printf("--------------------------------------------------------------------------------------------------------------------------\n");
        }
        printf("\n                                   Copyright (c) 2024 by 蒋仲勋, All Rights Reserved                          \n");
        printf("=========================================================================================================================\n\n");
        printf("请选择要修改的驳回申请记录: ");
        scanf("%d", &itemNum);
        printf("请输入新的查验项目名称: ");
        scanf("%s", newCheckItemName);
        bzero(sql, sizeof(sql));
        sprintf(sql, "UPDATE %s SET checkItemName = '%s', updateTime = dateTime('now', 'localtime') WHERE checkId = %d;",
                CHECK_TABLE_NAME, newCheckItemName, itemNum);
        ret = execOperate(db, sql, &errmsg, operationName);
        if (0 != ret)
        {
            fprintf(stderr, "已驳回记录【%d】修改失败! %s\n", itemNum, errmsg ? errmsg : "通用的SQL增删改操作error");
            return -1;
        }
        else
        {
            printf("已驳回记录【%d】修改成功!\n", itemNum);
            // 记录日志
            snprintf(message, sizeof(message), "【%s】修改了已驳回记录【%d】", applyUser, itemNum);
            logToLogInfoTable(db, OPERATELOG, message);
        }
    }
    return 0;
}

/**
 * @description: 删除用户个人的办结(已查验)记录
 * @param {sqlite3} *db SQLite3数据库指针句柄
 * @return {*} 成功返回0，失败返回非0的数
 */
int deleteCheckItem(sqlite3 *db, char *applyUser)
{
    char *errmsg = NULL;
    int row, column;
    char **result = NULL;
    char sql[256] = {0};
    char *operationName = "checkInfo";
    char message[128] = {0};
    int ret;
    int itemNum; // 选择删除的办结(已查验)记录编号
    sprintf(sql, "SELECT * FROM %s WHERE applyUser = '%s' AND checkStatus = %d AND isDelete = %d;",
            CHECK_TABLE_NAME, applyUser, CHECKED, DELETE_NO);
    // 调用 conditionQuery 执行查询操作
    result = conditionQuery(db, sql, &result, &row, &column, &errmsg, operationName);
    if (result == NULL)
    {
        fprintf(stderr, "查询失败: %s\n", errmsg ? errmsg : "未知错误");
        return -1;
    }
    if (0 == row)
    {
        printf("没有查到任何办结(已查验)信息!\n");
    }
    else
    {
        // 悉数打印 row 行记录的数据
        int i, j;
        printf("=============================================== XX 海关进出口智慧查验平台 ================================================\n\n");
        for (i = 0; i <= row; i++)
        {
            for (j = 0; j < column; j++)
            {
                // 如果是 checkStatus 列
                if (j == 4)
                {
                    // 判断 checkStatus 的值，替换为对应的文字
                    if (0 == strcmp(result[i * column + j], "0"))
                    {
                        printf("未查验\t");
                    }
                    else if (0 == strcmp(result[i * column + j], "1"))
                    {
                        printf("已查验\t");
                    }
                    else if (0 == strcmp(result[i * column + j], "2"))
                    {
                        printf("已驳回\t");
                    }
                    else
                    {
                        printf("%s\t", result[i * column + j]); // 保持原样
                    }
                }
                else if (j == 5)
                {
                    // 判断 checkType 的值，替换为对应的文字
                    if (0 == strcmp(result[i * column + j], "0"))
                    {
                        printf("系统自动查验\t");
                    }
                    else if (0 == strcmp(result[i * column + j], "1"))
                    {
                        printf("人工手动查验\t");
                    }
                    else
                    {
                        printf("%s\t", result[i * column + j]); // 保持原样
                    }
                }
                else
                {
                    // 对于非 checkStatus 和 checkType 列，直接输出原值
                    printf("%s\t", result[i * column + j]);
                    // fflush(stdout); // 强制刷新缓冲区
                }
            }
            printf("\n");
            printf("--------------------------------------------------------------------------------------------------------------------------\n");
        }
        printf("\n                                   Copyright (c) 2024 by 蒋仲勋, All Rights Reserved                          \n");
        printf("=========================================================================================================================\n\n");
        printf("请选择要删除的办结(已查验)申请记录: ");
        scanf("%d", &itemNum);
        bzero(sql, sizeof(sql));
        sprintf(sql, "UPDATE %s SET isDelete = %d, updateTime = dateTime('now', 'localtime') WHERE checkId = %d;",
                CHECK_TABLE_NAME, DELETE_YES, itemNum);
        ret = execOperate(db, sql, &errmsg, operationName);
        if (0 != ret)
        {
            fprintf(stderr, "已查验记录【%d】删除失败! %s\n", itemNum, errmsg ? errmsg : "通用的SQL增删改操作error");
            return -1;
        }
        else
        {
            printf("已查验记录【%d】删除成功!\n", itemNum);
            // 记录日志
            snprintf(message, sizeof(message), "【%s】删除了已查验记录【%d】", applyUser, itemNum);
            logToLogInfoTable(db, OPERATELOG, message);
        }
    }
    return 0;
}

/**
 * @description: 普通用户服务端通信
 * @param {int} newfd 套接字
 * @return {*} 成功返回0，失败返回-1
 */
int userTcpServerCom(int newfd, sqlite3 *db)
{
    // 判断入参
    if (newfd < 0)
    {
        printf("newfd is error");
        return -1;
    }
    int recvCount_user;
    // int temp_res_user;
    // char msgToClient_user[128]; // 接收客户端消息
    char buf_user[64] = {0};
    // 接收客户端发来的：业务种类@业务名称
    int totalCount = 0;
    bzero(buf_user, sizeof(buf_user)); // 清空缓冲区
    while (totalCount < sizeof(buf_user))
    {
        int bytesLeft = sizeof(buf_user) - totalCount;
        // recvCount_user = recv(newfd, buf_user, sizeof(buf_user), 0);
        recvCount_user = recv(newfd, buf_user + totalCount, bytesLeft, 0);
        if (recvCount_user > 0)
        {
            totalCount += recvCount_user;
            // 当接收到的数据量达到缓冲区大小时，手动添加结束符
            if (totalCount >= sizeof(buf_user))
            {
                buf_user[sizeof(buf_user) - 1] = '\0'; // 强制结束符
            }
            // buf_user[totalCount] = '\0'; // 确保字符串以 '\0' 结束
            // attempts = 0; // Reset attempts on successful receive
            printf("recvCount_user: %d, totalCount: %d\n", recvCount_user, totalCount);
        }
        else if (0 == recvCount_user)
        {
            printf("userSys客户端选择退出!\n");
            return -1;
        }
        else if (recvCount_user < 0)
        {
            if (errno == EAGAIN || errno == EWOULDBLOCK)
            {
                // 没有数据可读取，继续等待其他事件
                usleep(1000); // 等待一小段时间后再继续尝试接收
                continue;     // 继续下一轮循环，等待更多数据
            }
            else
            {
                perror("userSys recv error");
                return -1; // 处理其他错误
            }
        }
    }
    // 这里需要确保你在后续操作中处理字符串时避免超出
    printf("userSys Final buf: %s\n", buf_user); // 打印最终的 buf 内容
    printf("userSys totalCount = %d\n", totalCount);
    printf("userSys接收业务种类@业务名称,成功! buf_user = %s\n", buf_user);
    // 解析数据
    char *res[5] = {NULL};
    if (totalCount == 0 || buf_user[0] == '\0')
    {
        printf("接收到的 buf 为空，终止操作。\n");
        return -1;
    }
    parseStringUtil(buf_user, res);
    printf("业务数据解析成功!\n");
    // 按照业务名称进行模块处理
    // 发起查验申请业务
    if ((0 == strncasecmp(res[0], "user", 4)) && (0 == strncasecmp(res[1], "check", 5)))
    {
        // 调用发起查验申请接口
        // applyNewCheck(db, res[2]);
        printf("【%s】执行了【发起查验申请业务】操作!\n", res[2]);
    }
    // 查验申请记录业务
    else if ((0 == strncasecmp(res[0], "user", 4)) && (0 == strncasecmp(res[1], "search", 6)))
    {
        // 调用查验申请记录接口
        // searchCheckItem(db, res[2]);
        printf("【%s】执行了【查验申请记录业务】操作!\n", res[2]);
    }
    // 修改驳回申请业务
    else if ((0 == strncasecmp(res[0], "user", 4)) && (0 == strncasecmp(res[1], "update", 6)))
    {
        // 调用修改驳回申请接口
        // updateCheckItem(db, res[2]);
        printf("【%s】执行了【修改驳回申请业务】操作!\n", res[2]);
    }
    // 删除办结记录业务
    else if ((0 == strncasecmp(res[0], "user", 4)) && (0 == strncasecmp(res[1], "delete", 6)))
    {
        // 调用删除办结记录接口
        // deleteCheckItem(db, res[2]);
        printf("【%s】执行了【删除办结记录业务】操作!\n", res[2]);
    }
    // 退出
    else if ((0 == strncasecmp(res[0], "user", 4)) && (0 == strncasecmp(res[1], "quit", 4)))
    {
        printf("【%s】执行了【退出】操作!\n", res[2]);
        return -1;
    }
    return 0;
}
